package com.itheima.a05;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.context.support.GenericApplicationContext;

import java.io.IOException;

/*
    BeanFactory 后处理器的作用
 */
public class A05 {
    private static final Logger log = LoggerFactory.getLogger(A05.class);

    public static void main(String[] args) throws IOException {

        // ⬇️GenericApplicationContext 是一个【干净】的容器
        GenericApplicationContext context = new GenericApplicationContext();
        context.registerBean("config", Config.class);
//        context.registerBean(ConfigurationClassPostProcessor.class);
//        context.registerBean(MapperScannerConfigurer.class,bd->{
//            bd.getPropertyValues().add("basePackage","com.itheima.a05.mapper");
//        });
//        ComponentScan componentScan = AnnotationUtils.findAnnotation(Config.class, ComponentScan.class);
//        if (componentScan != null) {
//            for (String p : componentScan.basePackages()) {
//                System.out.println(p);
//                // com.itheima.a05.component-> classpath*:com/itheima/a05/component/**/*.class
//                String path = "classpath*:" + p.replace(".", "/") + "/**/*.class";
//                System.out.println(path);
//                CachingMetadataReaderFactory factory = new CachingMetadataReaderFactory();
//                for (Resource resource : context.getResources(path)) {
//                    System.out.println(resource);
//                    MetadataReader reader = factory.getMetadataReader(resource);
//                    System.out.println("类名" + reader.getClassMetadata().getClassName());
//                    System.out.println("是否加了Component:" + reader.getAnnotationMetadata().hasAnnotation(Component.class.getName()));
//                    System.out.println("是否加了Component派生注解:" + reader.getAnnotationMetadata().hasMetaAnnotation(Component.class.getName()));
//                }
//
//            }
//        }
//        CachingMetadataReaderFactory factory = new CachingMetadataReaderFactory();
//        MetadataReader reader = factory.getMetadataReader(new ClassPathResource("com/itheima/a05/Config.class"));
//        Set<MethodMetadata> methods = reader.getAnnotationMetadata().getAnnotatedMethods(Bean.class.getName());
//        for (MethodMetadata method : methods) {
//            System.out.println(method);
//            String initMethod = method.getAnnotationAttributes(Bean.class.getName()).get("initMethod").toString();
//
//
//            BeanDefinitionBuilder builder = BeanDefinitionBuilder.genericBeanDefinition();
//            builder.setFactoryMethodOnBean(method.getMethodName(),"config");
//            builder.setAutowireMode(AbstractBeanDefinition.AUTOWIRE_CONSTRUCTOR);
//            if (!initMethod.isEmpty()){
//                builder.setInitMethodName(initMethod);
//            }
//            AbstractBeanDefinition bd = builder.getBeanDefinition();
//            context.getDefaultListableBeanFactory().registerBeanDefinition(method.getMethodName(),bd);
//        }
        context.registerBean(AtBeanPostProcessor.class);
        context.registerBean(MapperPostProcessor.class);
/*        context.registerBean(ConfigurationClassPostProcessor.class); // @ComponentScan @Bean @Import @ImportResource
        context.registerBean(MapperScannerConfigurer.class, bd -> { // @MapperScanner
            bd.getPropertyValues().add("basePackage", "com.itheima.a05.mapper");
        });

        context.registerBean(ComponentScanPostProcessor.class); // 解析 @ComponentScan*/

/*        context.registerBean(AtBeanPostProcessor.class); // 解析 @Bean
        context.registerBean(MapperPostProcessor.class); // 解析 Mapper 接口*/

        // ⬇️初始化容器
        context.refresh();

        for (String name : context.getBeanDefinitionNames()) {
            System.out.println(name);
        }

/*        Mapper1 mapper1 = context.getBean(Mapper1.class);
        Mapper2 mapper2 = context.getBean(Mapper2.class);*/

        // ⬇️销毁容器
        context.close();

        /*
            学到了什么
                a. @ComponentScan, @Bean, @Mapper 等注解的解析属于核心容器(即 BeanFactory)的扩展功能
                b. 这些扩展功能由不同的 BeanFactory 后处理器来完成, 其实主要就是补充了一些 bean 定义
         */
    }
}
